console.log('this NB hook!')

// console.log(urlParsed)

let baseURL = window.location.protocol + '//' + window.location.host

/**
 * 由于系统的location有些方法不能更改，所以复刻然后使用
 */
/*
window.locatioon = {}
for (let key in window.location) {
    let value = window.location[key]
    window.locatioon[key] = value
}
*/
let hostnameAndPort = urlParsed.netloc.split(':')
let hostname = hostnameAndPort[0]
let port = urlParsed.scheme == 'http' ? '80' : '443'
if (hostnameAndPort.length > 1) {
    port = hostnameAndPort[1]
}
let href = urlParsed.scheme + '://' + urlParsed.netloc + urlParsed.path
if (urlParsed.query) {
    href = href + '?' + urlParsed.query
}

window.locatioon = {
    hash: '#' + urlParsed.fragment,
    href: href,
    protocol: urlParsed.scheme + ':',
    host: urlParsed.netloc,
    hostname: hostname,
    port: port,
    pathname: urlParsed.path,
    search: urlParsed.query,
    assign: function (...args) {
        console.log('window.locatioon.assign()', args)
    },
    reload: function (...args) {
        console.log('window.locatioon.reload()', args)
    },
    replace: function (...args) {
        let url = args[0]
        console.log('window.locatioon.replace()', args)
        window.location.replace(url)
    }
}
document.locatioon = window.locatioon
locatioon = window.locatioon

document.domaiin = document.locatioon.hostname

window.historry = {
    pushState: function (...args) {
        let state = args[0]
        let title = args[1]
        let url = args[2]

        let nUrl = url
        if (url && url.indexOf(location.hostname) < 0) {
            nUrl = webviewUrlCompletion(url, urlParsed)
            args[2] = nUrl
        }

        history.pushState(state, title, nUrl)
    }
}
historry = window.historry

/**
 * 在即将离开当前页面(刷新或关闭)时执行
 * 该事件可用于弹出对话框，提示用户是继续浏览页面还是离开当前页面。
 * @returns 自定义提示语
 */
/*
window.onbeforeunload = function(){
    return '确定要离开吗？'
}
*/

let getQueryVariable = function (variable) {
    var query = window.location.search.substring(1);
    var vars = query.split("&");
    for (var i=0;i<vars.length;i++) {
            var pair = vars[i].split("=");
            if(pair[0] == variable){return pair[1];}
    }
    return(false);
}

let referer = getQueryVariable('Referer')
if (referer) {
    referer = decodeURI(atob(referer))
}
document.referreer = referer || ''

let webviewUrlCompletion = function (url, urlParsedResult) {
    // print(urlParsedResult)

    url = url.trim()
    nURl = url

    // data:image 、 https:// 、 http:// 、 javascript: 、 #
    if (url && url.indexOf('data:image') != 0 && url.indexOf('https://') != 0 && url.indexOf('http://') != 0 && url.indexOf('javascript:') != 0 && url.indexOf('#') != 0) {
        if (url.indexOf('//') == 0) {
            nURl = urlParsedResult.scheme + ":" + url
        } else if (url.indexOf('/') == 0) {
            nURl = urlParsedResult.scheme + "://" + urlParsedResult.netloc + url
        } else{
            nURl = urlParsedResult.scheme + "://" + urlParsedResult.netloc + urlParsedResult.path + '/../' + url
        }
    }

    if (nURl.indexOf('https://') == 0 || nURl.indexOf('http://') == 0) {
        nUrlBase64 = btoa(encodeURI(nURl))
        Referer = btoa(encodeURI(urlParsedResult.scheme + "://" + urlParsedResult.netloc))
        nURl = urlParsedResult.webviewProxyUrl + '?url=' + nUrlBase64 + '&Referer=' + Referer
    }

    return nURl
}

function Hooks() {
    return {
        initEnv: function() {
            function getFuncName(fn) {
                // 获取函数名
                var strFunc = fn.toString()
                var _regex = /function\s+(\w+)\s*\(/
                var patten = strFunc.match(_regex)
                if (patten) {
                    return patten[1]
                }
                return ''
            }

            Function.prototype.hook = function(hookFunc, context) {
                var _context = context || window
                var _funcName =  getFuncName(this)
                if (!_funcName || _context[_funcName].prototype && _context[_funcName].prototype.isHooked) {
                    console.log("Already has been hooked,unhook first")
                    return false
                }
                _context['realFunc_' + _funcName] = this
                try {
                    eval('_context[_funcName] = function ' + _funcName + '(){\n' + 'var args = Array.prototype.slice.call(arguments,0)\n' + 'var obj = this\n' + 'return hookFunc.apply(obj,args) ? _context["realFunc_' + _funcName + '"].apply(obj,args) : false\n' + '}')
                    _context[_funcName].prototype.isHooked = true

                    return true
                } catch (e) {
                    console.log("Hook failed,check the params.")
                    return false
                }
            }
            Function.prototype.unhook = function(context) {
                var _context = context || window
                var _funcName = getFuncName(this)
                if (!_funcName || !_context[_funcName].prototype.isHooked) {
                    console.log("No function is hooked on")
                    return false
                }
                _context[_funcName] = _context['realFunc_' + _funcName]
                delete _context['realFunc_' + _funcName]
                return true
            }
        },
        cleanEnv: function() {
            if (Function.prototype.hasOwnProperty("hook")) {
                delete Function.prototype.hook
            }
            if (Function.prototype.hasOwnProperty("unhook")) {
                delete Function.prototype.unhook
            }
            return true
        }
    }
}

var hook = Hooks()
hook.initEnv()

setTimeout.hook(function (func, time) {
    if (3000 == time) {
        return false
    }
    return true
}, window)
// setTimeout.unhook()

// hook XMLHttpRequest.open()
let XMLHttpRequestOpenBackup = XMLHttpRequest.prototype.open
XMLHttpRequest.prototype.open = function(...args){
    let method = args[0]
    let url = args[1]
    let async = args[2]
    let username = args[3]
    let password = args[4]

    nUrl = webviewUrlCompletion(url, urlParsed)
    args[1] = nUrl

    return XMLHttpRequestOpenBackup.apply(this, args)
}

let ElementHook = {
    appendChild: Element.prototype.appendChild,
    insertBefore: Element.prototype.insertBefore,
    elementPacking (element) {
        let nodeName = element.nodeName
    
        if (nodeName.toLowerCase() == 'script') {
            let src = element.getAttribute('src')
            if (src) {
                let nSrc = webviewUrlCompletion(src, urlParsed)
                element.setAttribute("src", nSrc)
            }
        }

        if (nodeName.toLowerCase() == 'link') {
            let href = element.getAttribute('href')
            if (href) {
                let nHref = webviewUrlCompletion(href, urlParsed)
                element.setAttribute("href", nHref)
            }
        }

        if (nodeName.toLowerCase() == 'iframe') {
            let src = element.getAttribute('src')
            if (src) {
                let nSrc = webviewUrlCompletion(src, urlParsed)
                element.setAttribute("src", nSrc)
            }
        }

        if (nodeName.toLowerCase() == 'video') {
            let src = element.getAttribute('src')
            if (src) {
                let nSrc = webviewUrlCompletion(src, urlParsed)
                element.setAttribute("src", nSrc)
            }
        }

        if (nodeName.toLowerCase() == 'audio') {
            let src = element.getAttribute('src')
            if (src) {
                let nSrc = webviewUrlCompletion(src, urlParsed)
                element.setAttribute("src", nSrc)
            }
        }

        if (nodeName.toLowerCase() == 'img') {
            let src = element.getAttribute('src')
            if (src) {
                let nSrc = webviewUrlCompletion(src, urlParsed)
                element.setAttribute("src", nSrc)
            }
        }

        if (nodeName.toLowerCase() == 'embed') {
            let src = element.getAttribute('src')
            if (src) {
                let nSrc = webviewUrlCompletion(src, urlParsed)
                element.setAttribute("src", nSrc)
            }
        }

        if (nodeName.toLowerCase() == 'a') {
            let href = element.getAttribute('href')
            if (href) {
                let nHref = webviewUrlCompletion(href, urlParsed)
                element.setAttribute("href", nHref)
                element.setAttribute("target", '_self')
            }
        }

        return element
    },
    listeningElementAttr (element) {
        let nodeName = element.nodeName.toLowerCase()
        let srcTagMap = {'embed': true, 'img': true, 'audio': true, 'video': true}
        let hrefTagMap = {'a': true}

        // 监听元素属性变化
        try {
            if (srcTagMap[nodeName]) {
                Object.defineProperty(element, 'src', {
                    set: function (value) {
                        if (value && value.indexOf(location.hostname) < 0) {
                            value = webviewUrlCompletion(value, urlParsed)
                            element.setAttribute("src", value)
                        }
                    },
                    get: function () {
                        return element.getAttribute('src')
                    }
                })
            }
            if (hrefTagMap[nodeName]) {
                Object.defineProperty(element, 'href', {
                    set: function (value) {
                        if (value && value.indexOf(location.hostname) < 0) {
                            value = webviewUrlCompletion(value, urlParsed)
                            element.setAttribute("href", value)
                        }
                    },
                    get: function () {
                        return element.getAttribute('href')
                    }
                })
            }
        } catch (e) {
            console.error(e)
            console.log(element)
        }
    },
    listeningElementByTagName (tagName) {
        let elements = document.getElementsByTagName(tagName)
        for (let i = 0; i < elements.length; i++) {
            let element = elements[i]
            ElementHook.elementPacking(element)

            ElementHook.listeningElementAttr(element)
        }
    },
    init () {
        ElementHook.initDOMContentLoaded()
        ElementHook.initOnLoad()

        Element.prototype.appendChild = function(...args){
            let element = args[0]
            args[0] = ElementHook.elementPacking(element)
            ElementHook.listeningElementAttr(element)

            return ElementHook.appendChild.apply(this, args)
        }
        Element.prototype.insertBefore = function(...args){
            let element = args[0]
            args[0] = ElementHook.elementPacking(element)
            ElementHook.listeningElementAttr(element)

            return ElementHook.insertBefore.apply(this, args)
        }
    },
    initOnLoad () {
        window.addEventListener("load", function () {
        }, true)
    },
    initDOMContentLoaded () {
        document.addEventListener("DOMContentLoaded", function(event) {
            ElementHook.listeningElementByTagName('audio')
            ElementHook.listeningElementByTagName('a')
            ElementHook.listeningElementByTagName('img')
            ElementHook.listeningElementByTagName('embed')
        })
    }
}
ElementHook.init()

let fetchBackup = fetch
fetch = function (...args) {
    let url = args[0]
    let data = args[1]

    let nUrl = webviewUrlCompletion(url, urlParsed)
    args[0] = nUrl

    let result = fetchBackup.apply(window, args)

    /* 
    result.then(res => {
        console.log('fetch', {url, data, nUrl}, res)
    }).catch(err => {
        console.err('fetch', {url, data, nUrl}, res)
    })
     */

    return result
}

let windowOpenBackup = window.open
window.open = function (...args) {
    let url = args[0]
    let name = args[1]
    let features = args[2]
    let replace = args[3]

    if (url.indexOf(location.hostname) < 0) {
        let nUrl = webviewUrlCompletion(url, urlParsed)
        args[0] = nUrl
    }

    args[1] = '_self'

    return windowOpenBackup.apply(window, args)
}

Object.defineProperty(Element.prototype, "appendChild", {
    enumerable: false,
    configurable: false,
    writable: false,
    value: Element.prototype.appendChild
})
Object.defineProperty(Element.prototype, "insertBefore", {
    enumerable: false,
    configurable: false,
    writable: false,
    value: Element.prototype.insertBefore
})

Object.defineProperty(HTMLElement.prototype, "appendChild", {
    enumerable: false,
    configurable: false,
    writable: false,
    value: HTMLElement.prototype.appendChild
})
Object.defineProperty(HTMLElement.prototype, "insertBefore", {
    enumerable: false,
    configurable: false,
    writable: false,
    value: HTMLElement.prototype.insertBefore
})

for (let key in console) {
    Object.defineProperty(console, key, {
        enumerable: false,
        configurable: false,
        writable: false,
        value: console[key]
    })
}

Object.defineProperty(Object, "defineProperty", {
    enumerable: false,
    configurable: false,
    writable: false,
    value: Object.defineProperty
})

/*
let mutationObserver = window.MutationObserver || window.WebKitMutationObserver || window.MozMutationObserver
mutationObserver.prototype.observe = function (...args) {
    console.log('MutationObserver.prototype.observe', args)
}

Element.prototype.removeChild = function (...args) {
    console.log('Element.prototype.removeChild', args)
}
*/

// 动态添加数据采集插件js
document.write('<link rel="stylesheet" type="text/css" href="' + baseURL + '/static/css/databook.css' + '"><\/link>');
document.write('<script type="text/javascript" src="' + baseURL + '/static/js/databook.js' + '" ><\/script>');
